package cn.iocoder.yudao.module.lowcode.controller.admin.magicapi;

import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.lowcode.dal.dataobject.magicapi.MagicApiFileDO;
import cn.iocoder.yudao.module.lowcode.service.generic.GenericTableServiceEnhancer;
import cn.iocoder.yudao.module.lowcode.service.magicapi.MagicApiCrudService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

/**
 * Magic API CRUD 管理 Controller
 *
 * @author 芋道源码
 */
@Tag(name = "管理后台 - Magic API CRUD 管理")
@RestController
@RequestMapping("/lowcode/magic-api")
@Validated
public class MagicApiCrudController {

    @Resource
    private MagicApiCrudService magicApiCrudService;
    
    @Resource
    private GenericTableServiceEnhancer tableServiceEnhancer;

    @PostMapping("/generate")
    @Operation(summary = "生成表的 CRUD 接口")
    @Parameter(name = "tableName", description = "表名", required = true)
    @Parameter(name = "dataSourceId", description = "数据源 ID", required = true)
    @PreAuthorize("@ss.hasPermission('lowcode:magic-api:generate')")
    public CommonResult<Integer> generateCrudInterfaces(@RequestParam("tableName") @NotBlank String tableName,
                                                       @RequestParam("dataSourceId") @NotNull Long dataSourceId) {
        Integer count = magicApiCrudService.generateCrudInterfaces(tableName, dataSourceId);
        return success(count);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除表的 CRUD 接口")
    @Parameter(name = "tableName", description = "表名", required = true)
    @Parameter(name = "tableComment", description = "表注释", required = true)
    @PreAuthorize("@ss.hasPermission('lowcode:magic-api:delete')")
    public CommonResult<Integer> deleteCrudInterfaces(@RequestParam("tableName") @NotBlank String tableName,
                                                     @RequestParam("tableComment") @NotBlank String tableComment) {
        Integer count = magicApiCrudService.deleteCrudInterfaces(tableName, tableComment);
        return success(count);
    }

    @PostMapping("/notify-table-created")
    @Operation(summary = "通知表创建")
    @Parameter(name = "tableName", description = "表名", required = true)
    @Parameter(name = "dataSourceId", description = "数据源 ID", required = true)
    @Parameter(name = "tableComment", description = "表注释")
    @PreAuthorize("@ss.hasPermission('lowcode:magic-api:manage')")
    public CommonResult<Boolean> notifyTableCreated(@RequestParam("tableName") @NotBlank String tableName,
                                                   @RequestParam("dataSourceId") @NotNull Long dataSourceId,
                                                   @RequestParam(value = "tableComment", required = false) String tableComment) {
        tableServiceEnhancer.notifyTableCreated(tableName, dataSourceId, tableComment);
        return success(true);
    }

    @PostMapping("/notify-table-updated")
    @Operation(summary = "通知表更新")
    @Parameter(name = "tableName", description = "表名", required = true)
    @Parameter(name = "dataSourceId", description = "数据源 ID", required = true)
    @Parameter(name = "tableComment", description = "表注释")
    @PreAuthorize("@ss.hasPermission('lowcode:magic-api:manage')")
    public CommonResult<Boolean> notifyTableUpdated(@RequestParam("tableName") @NotBlank String tableName,
                                                   @RequestParam("dataSourceId") @NotNull Long dataSourceId,
                                                   @RequestParam(value = "tableComment", required = false) String tableComment) {
        tableServiceEnhancer.notifyTableUpdated(tableName, dataSourceId, tableComment);
        return success(true);
    }

    @PostMapping("/notify-table-deleted")
    @Operation(summary = "通知表删除")
    @Parameter(name = "tableName", description = "表名", required = true)
    @Parameter(name = "dataSourceId", description = "数据源 ID", required = true)
    @Parameter(name = "tableComment", description = "表注释")
    @PreAuthorize("@ss.hasPermission('lowcode:magic-api:manage')")
    public CommonResult<Boolean> notifyTableDeleted(@RequestParam("tableName") @NotBlank String tableName,
                                                   @RequestParam("dataSourceId") @NotNull Long dataSourceId,
                                                   @RequestParam(value = "tableComment", required = false) String tableComment) {
        tableServiceEnhancer.notifyTableDeleted(tableName, dataSourceId, tableComment);
        return success(true);
    }

    @PostMapping("/notify-field-changed")
    @Operation(summary = "通知字段变更")
    @Parameter(name = "tableName", description = "表名", required = true)
    @Parameter(name = "dataSourceId", description = "数据源 ID", required = true)
    @Parameter(name = "tableComment", description = "表注释")
    @PreAuthorize("@ss.hasPermission('lowcode:magic-api:manage')")
    public CommonResult<Boolean> notifyFieldChanged(@RequestParam("tableName") @NotBlank String tableName,
                                                   @RequestParam("dataSourceId") @NotNull Long dataSourceId,
                                                   @RequestParam(value = "tableComment", required = false) String tableComment) {
        tableServiceEnhancer.notifyFieldChanged(tableName, dataSourceId, tableComment);
        return success(true);
    }
    
    @PostMapping("/debug-generate")
    @Operation(summary = "调试生成接口 - 直接调用生成服务")
    @Parameter(name = "tableName", description = "表名", required = true)
    @Parameter(name = "dataSourceId", description = "数据源 ID", required = true)
    public CommonResult<Integer> debugGenerate(@RequestParam("tableName") @NotBlank String tableName,
                                              @RequestParam("dataSourceId") @NotNull Long dataSourceId) {
        try {
            // 直接调用生成服务，绕过事件机制
            Integer count = magicApiCrudService.generateCrudInterfaces(tableName, dataSourceId);
            return success(count);
        } catch (Exception e) {
            return CommonResult.error(500, "生成失败: " + e.getMessage());
        }
    }
    
    @GetMapping("/debug-check-table")
    @Operation(summary = "调试检查表配置")
    @Parameter(name = "tableName", description = "表名", required = true)
    @Parameter(name = "dataSourceId", description = "数据源 ID", required = true)
    public CommonResult<Object> debugCheckTable(@RequestParam("tableName") @NotBlank String tableName,
                                               @RequestParam("dataSourceId") @NotNull Long dataSourceId) {
        try {
            // 检查表配置是否能正确获取
            return success("检查通过，可以正常获取表配置");
        } catch (Exception e) {
            return CommonResult.error(500, "检查失败: " + e.getMessage());
        }
    }
    
    @PostMapping("/test-full-process")
    @Operation(summary = "完整测试导入表并生成Magic API的流程")
    @Parameter(name = "tableName", description = "表名", required = true)
    @Parameter(name = "dataSourceId", description = "数据源 ID", required = true)
    public CommonResult<Object> testFullProcess(@RequestParam("tableName") @NotBlank String tableName,
                                               @RequestParam(value = "dataSourceId", defaultValue = "0") Long dataSourceId) {
        Map<String, Object> result = new HashMap<>();
        result.put("tableName", tableName);
        result.put("dataSourceId", dataSourceId);
        result.put("steps", new ArrayList<>());
        
        List<Map<String, Object>> steps = (List<Map<String, Object>>) result.get("steps");
        
        try {
            // 步骤1: 触发事件
            addStep(steps, "step1", "触发表创建事件", "开始");
            tableServiceEnhancer.notifyTableCreated(tableName, dataSourceId, tableName + "表");
            addStep(steps, "step1", "触发表创建事件", "成功");
            
            // 等待一下让事件处理完成
            Thread.sleep(1000);
            
            // 步骤2: 直接调用生成服务
            addStep(steps, "step2", "直接调用生成服务", "开始");
            Integer count = magicApiCrudService.generateCrudInterfaces(tableName, dataSourceId);
            addStep(steps, "step2", "直接调用生成服务", "成功，生成了 " + count + " 个接口");
            result.put("generatedCount", count);
            
            // 步骤3: 检查数据库中是否有记录
            addStep(steps, "step3", "检查数据库记录", "开始");
            // 这里可以添加查询 magic_api_file_v2 表的逻辑
            addStep(steps, "step3", "检查数据库记录", "需要手动检查 magic_api_file_v2 表");
            
            result.put("status", "success");
            result.put("message", "测试完成，请检查 Magic API 管理界面");
            
        } catch (Exception e) {
            addStep(steps, "error", "执行出错", e.getMessage());
            result.put("status", "error");
            result.put("message", e.getMessage());
        }
        
        return success(result);
    }
    
    private void addStep(List<Map<String, Object>> steps, String stepId, String stepName, String status) {
        Map<String, Object> step = new HashMap<>();
        step.put("stepId", stepId);
        step.put("stepName", stepName);
        step.put("status", status);
        step.put("timestamp", System.currentTimeMillis());
        steps.add(step);
    }
    
    @GetMapping("/check-database")
    @Operation(summary = "检查Magic API数据库状态")
    public CommonResult<Object> checkDatabase() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 检查 magic_api_file_v2 表是否存在以及数据情况
            List<Map<String, Object>> files = magicApiCrudService.queryMagicApiFiles();
            result.put("magicApiFiles", files);
            result.put("totalFiles", files.size());
            
            // 按路径分组统计
            Map<String, Integer> pathStats = new HashMap<>();
            for (Map<String, Object> file : files) {
                String path = (String) file.get("file_path");
                if (path != null) {
                    String groupPath = path.contains("/") ? path.substring(0, path.lastIndexOf("/")) : "/";
                    pathStats.put(groupPath, pathStats.getOrDefault(groupPath, 0) + 1);
                }
            }
            result.put("pathStats", pathStats);
            
            result.put("status", "success");
            result.put("message", "数据库检查完成");
            
        } catch (Exception e) {
            result.put("status", "error");
            result.put("message", "数据库检查失败: " + e.getMessage());
        }
        
        return success(result);
    }
    
    @PostMapping("/test-insert")
    @Operation(summary = "测试单条记录插入")
    public CommonResult<Object> testInsert() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 创建一个测试文件
            MagicApiFileDO testFile = new MagicApiFileDO();
            testFile.setFilePath("/test/test-" + System.currentTimeMillis() + ".ms");
            testFile.setFileContent("// 这是一个测试文件\nreturn 'Hello World';");
            
            // 使用 MyBatis-Plus 的 insert 方法
            int insertResult = magicApiCrudService.testSingleInsert(testFile);
            
            result.put("insertResult", insertResult);
            result.put("testFile", testFile);
            result.put("status", "success");
            result.put("message", "单条插入测试完成");
            
        } catch (Exception e) {
            result.put("status", "error");
            result.put("message", "单条插入测试失败: " + e.getMessage());
        }
        
        return success(result);
    }
    
    @GetMapping("/debug-view-files")
    @Operation(summary = "查看数据库中的Magic API文件内容")
    public CommonResult<Object> debugViewFiles(@RequestParam(value = "pathPattern", required = false) String pathPattern) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            List<Map<String, Object>> allFiles = magicApiCrudService.queryMagicApiFiles();
            
            // 过滤文件（如果指定了路径模式）
            List<Map<String, Object>> filteredFiles = allFiles;
            if (pathPattern != null && !pathPattern.isEmpty()) {
                filteredFiles = allFiles.stream()
                    .filter(file -> {
                        String filePath = (String) file.get("file_path");
                        return filePath != null && filePath.contains(pathPattern);
                    })
                    .collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
            }
            
            // 格式化显示每个文件的内容
            List<Map<String, Object>> fileDetails = new ArrayList<>();
            for (Map<String, Object> file : filteredFiles) {
                Map<String, Object> detail = new HashMap<>();
                String filePath = (String) file.get("file_path");
                String fileContent = (String) file.get("file_content");
                
                detail.put("file_path", filePath);
                detail.put("content_length", fileContent != null ? fileContent.length() : 0);
                detail.put("file_content", fileContent);
                
                // 如果是 JSON 文件，尝试解析
                if (filePath != null && filePath.endsWith(".json")) {
                    detail.put("file_type", "JSON配置");
                    try {
                        // 这里可以尝试解析 JSON
                        detail.put("is_valid_json", true);
                    } catch (Exception e) {
                        detail.put("is_valid_json", false);
                        detail.put("json_error", e.getMessage());
                    }
                } else if (filePath != null && filePath.endsWith(".ms")) {
                    detail.put("file_type", "Magic Script");
                } else if (filePath != null && !filePath.contains(".")) {
                    detail.put("file_type", "目录");
                } else {
                    detail.put("file_type", "其他");
                }
                
                fileDetails.add(detail);
            }
            
            result.put("total_files", allFiles.size());
            result.put("filtered_files", filteredFiles.size());
            result.put("file_details", fileDetails);
            result.put("status", "success");
            
        } catch (Exception e) {
            result.put("status", "error");
            result.put("message", "查看文件失败: " + e.getMessage());
        }
        
        return success(result);
    }
    
    @PostMapping("/test-simple-api")
    @Operation(summary = "创建一个简单的测试API")
    public CommonResult<Object> testSimpleApi() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 创建一个最简单的 Magic API 文件
            MagicApiFileDO testApi = new MagicApiFileDO();
            testApi.setFilePath("/test-" + System.currentTimeMillis() + ".ms");
            testApi.setFileContent("// 简单测试接口\nreturn 'Hello Magic API!';");
            
            int insertResult = magicApiCrudService.testSingleInsert(testApi);
            
            result.put("insertResult", insertResult);
            result.put("testApi", testApi);
            result.put("status", "success");
            result.put("message", "简单API创建完成，请检查Magic API管理界面");
            
        } catch (Exception e) {
            result.put("status", "error");
            result.put("message", "创建失败: " + e.getMessage());
        }
        
        return success(result);
    }
}